/*!
 * \file DataManager.cpp
 * \project	WonderTrader
 *
 * \author Wesley
 * \date 2020/03/30
 * 
 * \brief 数据管理器实现文件
 * 
 * \details 本文件实现了WonderTrader数据服务系统的核心数据管理器类DataManager：
 *          - 实现数据写入器接口，处理各种行情数据
 *          - 管理数据写入器的动态加载和生命周期
 *          - 实现tick数据、Level2数据的写入和广播
 *          - 集成状态监控器进行会话状态管理
 *          - 配合UDP广播器进行实时数据分发
 *          - 提供历史数据转储和查询功能
 *          - 实现IDataWriterSink接口的所有回调方法
 */
#include "DataManager.h"
#include "StateMonitor.h"
#include "UDPCaster.h"
#include "WtHelper.h"

#include "../Includes/WTSVariant.hpp"
#include "../Share/DLLHelper.hpp"

#include "../WTSTools/WTSBaseDataMgr.h"
#include "../WTSTools/WTSLogger.h"

/**
 * @brief 构造函数
 * @details 初始化数据管理器，设置所有成员变量为NULL
 */
DataManager::DataManager()
	: _writer(NULL)
	, _bd_mgr(NULL)
	, _state_mon(NULL)
	, _udp_caster(NULL)
{
}

/**
 * @brief 析构函数
 * @details 清理数据管理器资源
 */
DataManager::~DataManager()
{
}

/**
 * @brief 检查会话是否已处理
 * @details 检查指定会话是否已经完成数据处理
 * @param sid 会话标识符
 * @return bool 会话是否已处理
 */
bool DataManager::isSessionProceeded(const char* sid)
{
	if (_writer == NULL)
		return false;

	return _writer->isSessionProceeded(sid);
}

/**
 * @brief 初始化数据管理器
 * @details 根据配置参数初始化数据管理器及其依赖组件，动态加载数据写入器模块
 * @param params 配置参数对象
 * @param bdMgr 基础数据管理器
 * @param stMonitor 状态监控器
 * @param caster UDP广播器（可选）
 * @return bool 初始化是否成功
 */
bool DataManager::init(WTSVariant* params, WTSBaseDataMgr* bdMgr, StateMonitor* stMonitor, UDPCaster* caster /* = NULL */)
{
	_bd_mgr = bdMgr;
	_state_mon = stMonitor;
	_udp_caster = caster;

	// 获取数据存储模块路径
	std::string module = params->getCString("module");
	if (module.empty())
		module = WtHelper::get_module_dir() + DLLHelper::wrap_module("WtDataStorage");
	else
		module = WtHelper::get_module_dir() + DLLHelper::wrap_module(module.c_str());
	
	// 动态加载数据存储模块
	DllHandle libParser = DLLHelper::load_library(module.c_str());
	if (libParser)
	{
		// 获取创建数据写入器的函数
		FuncCreateWriter pFuncCreateWriter = (FuncCreateWriter)DLLHelper::get_symbol(libParser, "createWriter");
		if (pFuncCreateWriter == NULL)
		{
			WTSLogger::error("Initializing of data writer failed: function createWriter not found...");
		}

		// 获取删除数据写入器的函数
		FuncDeleteWriter pFuncDeleteWriter = (FuncDeleteWriter)DLLHelper::get_symbol(libParser, "deleteWriter");
		if (pFuncDeleteWriter == NULL)
		{
			WTSLogger::error("Initializing of data writer failed: function deleteWriter not found...");
		}

		// 创建数据写入器实例
		if (pFuncCreateWriter && pFuncDeleteWriter)
		{
			_writer = pFuncCreateWriter();
			_remover = pFuncDeleteWriter;
		}
		WTSLogger::info_f("Data storage module {} loaded", module);
	}
	else
	{
		WTSLogger::error("Initializing of data writer failed: loading module %s failed...", module.c_str());
	}

	return _writer->init(params, this);
}

/**
 * @brief 添加扩展数据导出器
 * @details 注册一个扩展的历史数据导出器
 * @param id 导出器标识符
 * @param dumper 历史数据导出器接口
 */
void DataManager::add_ext_dumper(const char* id, IHisDataDumper* dumper)
{
	if (_writer == NULL)
		return;

	_writer->add_ext_dumper(id, dumper);
}

/**
 * @brief 释放数据管理器
 * @details 释放数据写入器资源，清理数据管理器状态
 */
void DataManager::release()
{
	if (_writer)
	{
		_writer->release();
		_remover(_writer);
	}
}

/**
 * @brief 写入tick数据
 * @details 处理和写入实时tick行情数据
 * @param curTick 当前tick数据
 * @param procFlag 处理标志
 * @return bool 写入是否成功
 */
bool DataManager::writeTick(WTSTickData* curTick, uint32_t procFlag)
{
	if (_writer == NULL)
		return false;

	return _writer->writeTick(curTick, procFlag);
}

/**
 * @brief 写入订单队列数据
 * @details 处理和写入Level2订单队列数据
 * @param curOrdQue 当前订单队列数据
 * @return bool 写入是否成功
 */
bool DataManager::writeOrderQueue(WTSOrdQueData* curOrdQue)
{
	if (_writer == NULL)
		return false;

	return _writer->writeOrderQueue(curOrdQue);
}

/**
 * @brief 写入订单明细数据
 * @details 处理和写入Level2订单明细数据
 * @param curOrdDtl 当前订单明细数据
 * @return bool 写入是否成功
 */
bool DataManager::writeOrderDetail(WTSOrdDtlData* curOrdDtl)
{
	if (_writer == NULL)
		return false;

	return _writer->writeOrderDetail(curOrdDtl);
}

/**
 * @brief 写入逐笔成交数据
 * @details 处理和写入Level2逐笔成交数据
 * @param curTrans 当前逐笔成交数据
 * @return bool 写入是否成功
 */
bool DataManager::writeTransaction(WTSTransData* curTrans)
{
	if (_writer == NULL)
		return false;

	return _writer->writeTransaction(curTrans);
}

/**
 * @brief 获取当前tick数据
 * @details 获取指定合约的最新tick数据
 * @param code 合约代码
 * @param exchg 交易所代码（默认为空）
 * @return WTSTickData* 当前tick数据指针
 */
WTSTickData* DataManager::getCurTick(const char* code, const char* exchg/* = ""*/)
{
	if (_writer == NULL)
		return NULL;

	return _writer->getCurTick(code, exchg);
}

/**
 * @brief 转储历史数据
 * @details 将指定会话的历史数据进行转储处理
 * @param sid 会话标识符
 */
void DataManager::transHisData(const char* sid)
{
	if (_writer)
		_writer->transHisData(sid);
}

//////////////////////////////////////////////////////////////////////////
#pragma region "IDataWriterSink接口实现"

/**
 * @brief 获取基础数据管理器
 * @details 获取基础数据管理器接口
 * @return IBaseDataMgr* 基础数据管理器指针
 */
IBaseDataMgr* DataManager::getBDMgr()
{
	return _bd_mgr;
}

/**
 * @brief 检查会话是否可接收数据
 * @details 检查指定会话是否处于可接收数据状态
 * @param sid 会话标识符
 * @return bool 会话是否可接收数据
 */
bool DataManager::canSessionReceive(const char* sid)
{
	//By Wesley @ 2021.12.27
	//如果状态监控器为NULL，说明是完全开放模式，直接返回true即可
	if (_state_mon == NULL)
		return true;

	return _state_mon->isInState(sid, SS_RECEIVING);
}

/**
 * @brief 广播tick数据
 * @details 通过UDP广播器广播tick数据
 * @param curTick 当前tick数据
 */
void DataManager::broadcastTick(WTSTickData* curTick)
{
	if (_udp_caster)
		_udp_caster->broadcast(curTick);
}

/**
 * @brief 广播订单明细数据
 * @details 通过UDP广播器广播订单明细数据
 * @param curOrdDtl 当前订单明细数据
 */
void DataManager::broadcastOrdDtl(WTSOrdDtlData* curOrdDtl)
{
	if (_udp_caster)
		_udp_caster->broadcast(curOrdDtl);
}

/**
 * @brief 广播订单队列数据
 * @details 通过UDP广播器广播订单队列数据
 * @param curOrdQue 当前订单队列数据
 */
void DataManager::broadcastOrdQue(WTSOrdQueData* curOrdQue)
{
	if (_udp_caster)
		_udp_caster->broadcast(curOrdQue);
}

/**
 * @brief 广播逐笔成交数据
 * @details 通过UDP广播器广播逐笔成交数据
 * @param curTrans 当前逐笔成交数据
 */
void DataManager::broadcastTrans(WTSTransData* curTrans)
{
	if (_udp_caster)
		_udp_caster->broadcast(curTrans);
}

/**
 * @brief 获取会话合约集合
 * @details 获取指定会话的合约代码集合
 * @param sid 会话标识符
 * @return CodeSet* 合约代码集合指针
 */
CodeSet* DataManager::getSessionComms(const char* sid)
{
	return  _bd_mgr->getSessionComms(sid);
}

/**
 * @brief 获取交易日期
 * @details 获取指定产品的当前交易日期
 * @param pid 产品标识符
 * @return uint32_t 交易日期（格式：YYYYMMDD）
 */
uint32_t DataManager::getTradingDate(const char* pid)
{
	return  _bd_mgr->getTradingDate(pid);
}

/**
 * @brief 输出日志信息
 * @details 输出指定级别的日志信息
 * @param ll 日志级别
 * @param message 日志消息
 */
void DataManager::outputLog(WTSLogLevel ll, const char* message)
{
	WTSLogger::log_raw(ll, message);
}

#pragma endregion "IDataWriterSink接口实现"
